home *** CD-ROM | disk | FTP | other *** search
/ Belgian Amiga Club - ADF Collection / BS1 part 41.zip / BS1 part 41 / parallel-C disk .adf / afserver.bak < prev    next >
Text File  |  1997-12-31  |  30KB  |  1,332 lines

  1. /**************************************************************************
  2. *
  3. *  Alien File Server
  4. *
  5. *  12th March 1987.
  6. *
  7. *  Copyright INMOS Limited, 1987.
  8. *
  9. *  Upgrade to 3L-Server by Gerhard Bartz
  10. *
  11. *  18th April 1989
  12. *
  13. ***************************************************************************/
  14.  
  15. #define LINT_ARGS 1      /* Enable Compiler Parameter Checking */
  16. #include <stdio.h>
  17. #include <stat.h>
  18. #include <time.h>
  19. #include <string.h>
  20.  
  21. #include "srvconst.h"
  22.  
  23. extern char *mktemp();   
  24.  
  25. extern unsigned int link_base;
  26. /* Server static variables */
  27. /* Transputer command line buffer. Contains parameters from the server */
  28. /* command line which the server does not recognise. */
  29. static char tcom[COMMAND_LINE_LENGTH];
  30. static int tcominptr = 0, tcomoutptr = 0;
  31. static int terminate_code;                    /* Server result */
  32. static int transputer_result = 0;             /* Result from transputer */
  33. static int command;
  34. static int boot_file_exists = FALSE;          /* If true, use boot file */
  35. static int alien_option_flag = 0x0;
  36. static char version[] =
  37.    "Alien file server V1.3 (14th October 1987) + 3L 15th January 1988\n";
  38. static char copyright[] =
  39.    "Copyright INMOS Ltd, 1985\n";
  40.  
  41. static struct STREAM_DESC filers[N_STREAMS];
  42.  
  43. static char *open_types [MAX_OPEN_MODE+1]
  44.   [MAX_EXIST_MODE+1][MAX_ACCESS_METHOD+1] =
  45.     { { { "r",  "r"  }, { "r",  "r" } },
  46.       { { "r+", "r+" }, { "w",  "w" } },
  47.       { { "r+", "r+" }, { "w+", "w+"} } };
  48. /* Server global variables */
  49. int running;                   /* Server is running flag */
  50. int test_error_flag = FALSE;   /* If true, test error flag */
  51.  
  52. void terminate_server (t_code)
  53. int t_code;
  54. /* Set flags to terminate the server. */
  55. {
  56.     terminate_code = t_code;
  57.     running = FALSE;
  58. }
  59.  
  60. int fexists (file_str)
  61. char *file_str;
  62. /* Return TRUE if the file whose name is in file_str exists,
  63.    FALSE otherwise. */
  64. {
  65.     FILE *stream;
  66.     if ( (stream = fopen (file_str, "r")) != NULL )
  67.     {
  68.         fclose (stream);
  69.         return (TRUE);
  70.     } else
  71.         return (FALSE);
  72. }
  73.  
  74. int filer_close_file (streamp, close_mode)
  75. struct STREAM_DESC *streamp;
  76. int close_mode;
  77. {
  78.     int res = F_OK;
  79.     if ( (close_mode >= 0) && (close_mode <= MAX_CLOSE_OPTION) )
  80.     {
  81.         if (streamp->lifetime_m != SPECIAL)
  82.         {
  83.             if (fclose (streamp->fileptr) == 0)
  84.             {
  85. if ((close_mode == CLOSEDEL_OPTION) ||
  86.     (streamp->lifetime_m == TEMPORARY))
  87. {
  88.     if (unlink (streamp->name) != 0)
  89.     {
  90.         res = OPERATIONFAILED_ERR;
  91.     };
  92. };
  93.                 streamp->inuse = FALSE;
  94.             } else
  95.             {
  96.                 res = OPERATIONFAILED_ERR;
  97.                 /* Remove our reference anyway */
  98.                 streamp->inuse = FALSE;
  99.             };
  100.         } else
  101.             streamp->inuse = FALSE; /* Just remove our reference */
  102.     } else
  103.         res = INVALIDCLOSEOPTION_ERR;
  104.     return (res);
  105. }
  106.  
  107. void filer_close ()
  108. {
  109.     int i;
  110.     for (i = 0; i < N_STREAMS; i++)
  111.         if ( filers[i].inuse )
  112.         {
  113.             filer_close_file ( &(filers[i]), CLOSE_OPTION );
  114.             filers[i].inuse = FALSE;
  115.         };
  116. }
  117.  
  118. void record_to_string (rec, len, str)
  119. char *rec;
  120. int len;
  121. char *str;
  122. {
  123.   int i;
  124.   for (i = 0; i < len; i++)
  125.     *str++ = rec[i];
  126.   *str = '\0';
  127. }
  128.  
  129. void string_to_record (str, rec, len)
  130. char *str;
  131. char *rec;
  132. int  *len;
  133. {
  134.     int i = 0;
  135.     while (*str != '\0')
  136.         rec[i++] = *str++;
  137.     *len = i;
  138. }
  139.  
  140. int find_stream ()
  141. {
  142.     int i = 0;
  143.     int found = FALSE;
  144.     while( (i < N_STREAMS) && (found == FALSE) )
  145.     {
  146.         if ((filers[i].inuse) == FALSE)
  147.             found = TRUE;
  148.         else
  149.             i++;
  150.     };
  151.     if (found)
  152.         return (i);
  153.     else
  154.         return (INVALID_STREAM);
  155. }
  156.  
  157.  
  158. int valid_stream (n)
  159. int n;
  160. {
  161.     if ( (n >= 0) && (n < N_STREAMS) )
  162.         if (filers[n].inuse)
  163.             return (TRUE);
  164.     return (FALSE);
  165. }
  166.  
  167. int make_file_name (n)
  168. char *n;
  169. {
  170.     char *template = "afXXXXXX";
  171.     char *result;
  172.     result = mktemp(template);
  173.     strcpy (n, result);
  174.     if (*n=='\0') return(FALSE);
  175.     return (TRUE);
  176. }
  177.  
  178. int make_af_err (c_err)
  179. int c_err;
  180. {
  181.     return (HOST_ERROR_BASE - c_err);
  182. }
  183.  
  184. int seek_file_length (fptr, length)
  185. FILE *fptr;
  186. long *length;
  187. {
  188.     long curpos;
  189.     int result = F_OK;
  190.     curpos = ftell(fptr);                    /* Remember where we are    */
  191.     if (fseek(fptr, 0L, 2) == 0)             /* Go to the end to find    */
  192.         *length = ftell(fptr);               /* where it is              */
  193.     else
  194.         result = OPERATIONFAILED_ERR;
  195.     if (fseek(fptr, curpos, 0) != 0)            /* Go back to where */
  196.         result = OPERATIONFAILED_ERR;          /* We were          */
  197.     return (result);
  198. }
  199.  
  200. int tag_from_link ()
  201. {
  202.     return (word_from_link());
  203. }
  204.  
  205. int read_integer (v)
  206. int *v;
  207. {
  208.     if (tag_from_link() == INT32_VALUE)
  209.     {
  210.         *v = word_from_link ();
  211.         return (TRUE);
  212.     } else
  213.     {
  214.         fprintf (stderr,"Last command = %n\n", command);
  215.         terminate_server (T_BAD_INT32);
  216.         return (FALSE);
  217.     };
  218. }
  219.  
  220. extern long int long_word_from_link();
  221. int read_long_integer (v)
  222. long int *v;
  223. {
  224.     if (tag_from_link() == INT32_VALUE)
  225.     {
  226.         *v = long_word_from_link ();
  227.         return (TRUE);
  228.     } else
  229.     {
  230.         fprintf (stderr,"Last command = %n\n", command);
  231.         terminate_server (T_BAD_INT32);
  232.         return(FALSE);
  233.     };
  234. }
  235.  
  236. int read_record (len, buffer)
  237. int *len;
  238. char *buffer;
  239. {
  240.     int t = tag_from_link ();
  241.     if (t == NILRECORD_VALUE)
  242.     {
  243.         *len = 0;
  244.         return (TRUE);
  245.     } else
  246.         if (t == RECORD32_VALUE)
  247.         {
  248.             *len = trunc_slice_from_link (RECORD_LENGTH, buffer);
  249.             return (TRUE);
  250.         } else
  251.         {
  252.             fprintf (stderr, "Last command = %n\n", command);
  253.             terminate_server (T_BAD_RECORD);
  254.             return (FALSE);
  255.         };
  256. }
  257.  
  258. int read_long_record (len, buffer)
  259. long int *len;
  260. char *buffer;
  261. {
  262.     int t = tag_from_link ();
  263.     if (t == NILRECORD_VALUE)
  264.     {
  265.         *len = 0;
  266.         return (TRUE);
  267.     } else
  268.         if (t == RECORD32_VALUE)
  269.         {
  270.             long_slice_from_link (len, buffer);
  271.             return (TRUE);
  272.         } else
  273.         {
  274.             fprintf (stderr, "Last command = %n\n", command);
  275.             terminate_server (T_BAD_RECORD);
  276.             return (FALSE);
  277.         };
  278. }
  279.  
  280. void tag_to_link (tag)
  281. int tag;
  282. {
  283.     word_to_link (tag);
  284. }
  285.  
  286. void write_integer (n)
  287. int n;
  288. {
  289.     tag_to_link (INT32_VALUE);
  290.     word_to_link (n);
  291. }
  292.  
  293. void write_long_integer (n)
  294. long int n;
  295. {
  296.     tag_to_link (INT32_VALUE);
  297.     long_word_to_link (n);
  298. }
  299.  
  300. void write_record (len, buffer)
  301. int len;
  302. char *buffer;
  303. {
  304.     if (len == 0)
  305.         tag_to_link (NILRECORD_VALUE);
  306.     else
  307.     {
  308.         tag_to_link (RECORD32_VALUE);
  309.         slice_to_link (len, buffer);
  310.     };
  311. }
  312.  
  313. void write_long_record (len, buffer)
  314. long int len;
  315. char *buffer;
  316. {
  317.     if (len == 0)
  318.         tag_to_link (NILRECORD_VALUE);
  319.     else
  320.     {
  321.         tag_to_link (RECORD32_VALUE);
  322.         long_slice_to_link (len, buffer);
  323.     };
  324. }
  325.  
  326. void open_temp ()
  327. {
  328.     int access_method, record_length;
  329.     int stream_id = INVALID_STREAM;
  330.     int res = F_OK;
  331.     if (read_integer (&access_method))
  332.     if (read_integer (&record_length))
  333. {
  334. if ((access_method >= 0) && (access_method <= MAX_ACCESS_METHOD))
  335. {
  336. stream_id = find_stream ();
  337. if (stream_id >= 0)
  338. {
  339.     struct STREAM_DESC *streamp = &filers[stream_id];
  340.     if (make_file_name (streamp->name))
  341.     {
  342. char *type = open_types[UPDATE_MODE][NEW_FILE][access_method];
  343. FILE *fptr;
  344. fptr = fopen (streamp->name, type);
  345. if (fptr != NULL)
  346. {
  347.     streamp->inuse = TRUE;
  348.     streamp->fileptr = fptr;
  349.     streamp->open_m = UPDATE_MODE;
  350.     streamp->exist_m = NEW_FILE;
  351.     streamp->access_m = access_method;
  352.     streamp->lifetime_m = TEMPORARY;
  353.     streamp->result = F_OK;
  354. } else
  355.     res = OPERATIONFAILED_ERR;
  356.     } else
  357.         res = OPERATIONFAILED_ERR;
  358. } else
  359.     res = NOFREECHANNEL_ERR;
  360. } else
  361.     res = INVALIDACCESSMETHOD_ERR;
  362. write_integer (stream_id);
  363. write_integer (res);
  364. };
  365. }
  366.  
  367. void open_file (lifetime)
  368. int lifetime;
  369. {
  370.     char filename [FILE_NAME_LENGTH];
  371.     int len = 0;
  372.     int access_method, open_mode, exist_mode, record_length;
  373.     int res = F_OK;
  374.     if (read_record (&len, filename))
  375.     if (read_integer (&access_method))
  376.     if (read_integer (&open_mode))
  377.     if (read_integer (&exist_mode))
  378.     if (read_integer (&record_length))
  379. {
  380.     int stream = INVALID_STREAM;
  381.     if ((access_method >= 0) && (access_method <= MAX_ACCESS_METHOD))
  382.     {
  383.         if ((open_mode >= 0) && (open_mode <= MAX_OPEN_MODE))
  384.         {
  385.             if ((exist_mode >= 0) && (exist_mode <= MAX_EXIST_MODE))
  386.             {
  387. stream = find_stream ();
  388. if (stream >= 0)
  389. {
  390.     struct STREAM_DESC *streamp = &filers[stream];
  391.     record_to_string (filename, len, streamp->name);
  392.     {
  393. char *type = open_types[open_mode][exist_mode][access_method];
  394. FILE *fptr;
  395. fptr = fopen (streamp->name, type);
  396. if (fptr != NULL)
  397. {
  398.     streamp->inuse = TRUE;
  399.     streamp->fileptr = fptr;
  400.     streamp->open_m = open_mode;
  401.     streamp->exist_m = exist_mode;
  402.     streamp->access_m = access_method;
  403.     streamp->lifetime_m = lifetime;
  404.     streamp->result = F_OK;
  405. } else
  406.     res = OPERATIONFAILED_ERR;
  407.     };
  408. } else
  409.     res = NOFREECHANNEL_ERR;
  410.             } else
  411.                 res = INVALIDEXISTMODE_ERR;
  412.         } else
  413.             res = INVALIDOPENMODE_ERR;
  414.     } else
  415.         res = INVALIDACCESSMETHOD_ERR;
  416.     write_integer (stream);
  417.     write_integer (res);
  418. };
  419. }
  420.  
  421. void open_stream (open_mode)
  422. int open_mode;
  423. {
  424.     int stream_id = INVALID_STREAM;
  425.     int std_stream_no;
  426.     int res = F_OK;
  427.     if (read_integer(&std_stream_no))
  428.     {
  429.         if (open_mode == S_INPUT)
  430.         { 
  431. switch (std_stream_no)
  432. {
  433. case 0:
  434.     stream_id = find_stream ();
  435.     if (stream_id >= 0)
  436.     {
  437. struct STREAM_DESC *streamp = &filers[stream_id];
  438. streamp->inuse = TRUE;
  439. strcpy (streamp->name, "stdin");
  440. streamp->fileptr = stdin;
  441. streamp->open_m = READ_MODE;
  442. streamp->exist_m = OLD_FILE;
  443. streamp->access_m = TEXTBYTESTREAM_ACCESS;
  444. streamp->lifetime_m = SPECIAL;
  445. streamp->result = F_OK;
  446.     } else
  447.         res = NOFREECHANNEL_ERR;
  448.     break;
  449. case 1:
  450.     stream_id = PARAM_STREAM;
  451.     break;
  452. default:
  453.     res = INVALIDSTDSTREAM_ERR;
  454. };
  455.         } else
  456.             if (open_mode == S_OUTPUT)
  457.             {
  458. switch (std_stream_no)
  459. {
  460. case 0:
  461.     stream_id = find_stream ();
  462.     if (stream_id >= 0)
  463.     {
  464. struct STREAM_DESC *streamp = &filers[stream_id];
  465. streamp->inuse = TRUE;
  466. strcpy (streamp->name, "stdout");
  467. streamp->fileptr = stdout;
  468. streamp->open_m = WRITE_MODE;
  469. streamp->exist_m = OLD_FILE;
  470. streamp->access_m = TEXTBYTESTREAM_ACCESS;
  471. streamp->lifetime_m = SPECIAL;
  472. streamp->result = F_OK;
  473.     } else
  474.         res = NOFREECHANNEL_ERR;
  475.     break;
  476. case 1:
  477.     stream_id = find_stream ();
  478.     if (stream_id >= 0)
  479.     {
  480. struct STREAM_DESC *streamp = &filers[stream_id];
  481. streamp->inuse = TRUE;
  482. strcpy (streamp->name, "stderr");
  483. streamp->fileptr = stderr;
  484. streamp->open_m = WRITE_MODE;
  485. streamp->exist_m = OLD_FILE;
  486. streamp->access_m = TEXTBYTESTREAM_ACCESS;
  487. streamp->lifetime_m = SPECIAL;
  488. streamp->result = F_OK;
  489.     } else
  490.         res = NOFREECHANNEL_ERR;
  491.     break;
  492. default:
  493.     res = INVALIDSTDSTREAM_ERR;
  494. };
  495.             };
  496.         write_integer (stream_id);
  497.         write_integer (res);
  498.     };
  499. }
  500.  
  501. void close_stream ()
  502. {
  503.     int stream_id = INVALID_STREAM;
  504.     int close_mode;
  505.     int res = F_OK;
  506.     if (read_integer(&stream_id))
  507.     if (read_integer(&close_mode))
  508.     {
  509.         if (valid_stream (stream_id))
  510.         {
  511.             res = filer_close_file (&(filers[stream_id]), close_mode);
  512.         } else
  513.         {
  514.             if (stream_id == PARAM_STREAM)
  515.                 tcomoutptr = 0;
  516.             else
  517.                 res = INVALIDSTREAMID_ERR;
  518.         };
  519.         write_integer (res);
  520.     };
  521. }
  522.  
  523. void read_block ()
  524. {
  525.     int stream_id = INVALID_STREAM;
  526.     int record_len = 0;
  527.     int res = F_OK;
  528.     int bytes_read = 0;
  529.     char buffer[RECORD_LENGTH];
  530.     if (read_integer (&stream_id))
  531.     if (read_integer (&record_len))
  532.     { 
  533.         if (valid_stream (stream_id))
  534. {
  535.     struct STREAM_DESC *streamp = &filers[stream_id];
  536.     if ((record_len >= 0) && (record_len <= RECORD_LENGTH))
  537.     {
  538.         if (streamp->fileptr == stdin)
  539.         {
  540.             int chr = '\0';
  541.             while ((chr != EOF) && (bytes_read < record_len))
  542.             {
  543.                 chr = getchar();
  544.                 buffer[bytes_read++] = chr;
  545.                 if (chr == EOF)
  546.                     bytes_read--;            /* Remove EOF from block */
  547.                 else if (chr == '\n')
  548.                     break;
  549.             }
  550.         } else
  551.             bytes_read = fread(buffer, 1, record_len, streamp->fileptr);
  552.         if (feof(streamp->fileptr))
  553.         {
  554.             streamp->result = F_EOF; res = F_EOF;
  555.         } else
  556.         {
  557.             int r = ferror(streamp->fileptr);
  558.             streamp->result = make_af_err(r);
  559.             if (r != 0)
  560.                 res = OPERATIONFAILED_ERR;
  561.         };
  562.     } else
  563.         res = INVALIDRECORDLENGTH_ERR;
  564.         } else
  565.         {
  566.             if (stream_id == PARAM_STREAM)
  567. {
  568.     if ((record_len >=0) && (record_len <= RECORD_LENGTH))
  569.     {
  570.         bytes_read = tcomread(buffer, record_len);
  571.         if (bytes_read < record_len)
  572.             res = F_EOF;
  573.     } else
  574.         res = INVALIDRECORDLENGTH_ERR;
  575.         } else
  576.             {
  577.                 res = INVALIDSTREAMID_ERR;
  578.             };
  579.         };
  580.         write_record (bytes_read, buffer);
  581.         write_integer (res);
  582.     };
  583. }
  584.  
  585. void write_block ()
  586. {
  587.     int stream_id = INVALID_STREAM;
  588.     int record_len = 0;
  589.     int bytes_written = 0;
  590.     char buffer [RECORD_LENGTH];
  591.     int res = F_OK;
  592.     if (read_integer (&stream_id))
  593.     if (read_record (&record_len, buffer))
  594.     {
  595.         if (valid_stream (stream_id))
  596. {
  597.     struct STREAM_DESC *streamp = &filers[stream_id];
  598.     bytes_written = fwrite (buffer, 1, record_len, streamp->fileptr);
  599.     if (bytes_written != record_len)
  600.     {
  601.         streamp->result = make_af_err(ferror(streamp->fileptr));
  602.         res = OPERATIONFAILED_ERR;
  603.     };
  604.         } else
  605.             res = INVALIDSTREAMID_ERR;
  606.         write_integer (bytes_written);
  607.         write_integer (res);
  608.     };
  609. }
  610.  
  611. void stream_seek ()
  612. {
  613.     int stream_id = INVALID_STREAM;
  614.     long int offset = 0;
  615.     int res = F_OK;
  616.     if (read_integer (&stream_id))
  617.     if (read_long_integer (&offset))
  618.     {
  619.         if (valid_stream (stream_id))
  620.         {
  621.             struct STREAM_DESC *streamp = &filers[stream_id];
  622.             int r;
  623.             if ((r = fseek(streamp->fileptr, offset, 0)) != 0)
  624.             {
  625.                 streamp->result = make_af_err(r);
  626.                 res = OPERATIONFAILED_ERR;
  627.             } else
  628.                 streamp->result = F_OK;
  629.         } else
  630.         {
  631.             if (stream_id == PARAM_STREAM)
  632.                 res = NOSEEKPOSSIBLE_ERR;
  633.             else
  634.                 res = INVALIDSTREAMID_ERR;
  635.         };
  636.         write_integer (res);
  637.     };
  638. }
  639.  
  640. void stream_file ()
  641. {
  642.     int stream_id;
  643.     if (read_integer (&stream_id))
  644.     {
  645.         char filename[RECORD_LENGTH];
  646.         int len = 0;
  647.         int res = F_OK;
  648.         if (valid_stream(stream_id))
  649.         {
  650.             struct STREAM_DESC *streamp = &filers[stream_id];
  651.             string_to_record (streamp->name, filename, &len);
  652.         } else
  653.         {
  654.             if (stream_id == PARAM_STREAM)
  655.                 string_to_record ("Command line", filename, &len);
  656.             else
  657.                 res = INVALIDSTREAMID_ERR;
  658.         };
  659.         write_record (len, filename);
  660.         write_integer (res);
  661.     };
  662. }
  663.  
  664. void stream_connect ()
  665. {
  666.     int stream_id;
  667.     if (read_integer (&stream_id))
  668.     {
  669.         int device_connected = -1;
  670.         int res = F_OK;
  671.         if (valid_stream(stream_id))
  672. {
  673.     struct STREAM_DESC *streamp = &filers[stream_id];
  674.     struct stat buffer;
  675.     if (stat(streamp->name, &buffer) == 0)
  676.     {
  677. if (isatty(fileno(streamp->fileptr)))
  678. {   /* We are connected to a device */
  679.     if (strcmp ("stdin", streamp->name) == 0)
  680.         device_connected = KEYBOARD_USE;
  681.     else
  682.     {
  683.         if ((strcmp ("stdout", streamp->name) == 0) ||
  684.             (strcmp ("stderr", streamp->name) == 0))
  685.             device_connected = SCREEN_USE;
  686.         else
  687.             res = OPERATIONFAILED_ERR;
  688.     };
  689. } else
  690. {
  691.     if (buffer.st_attr & ST_DELETE)
  692.     { /* We are connected to a file */
  693.         if (streamp->lifetime_m == TEMPORARY)
  694.             device_connected = TEMP_USE;
  695.         else
  696.             device_connected = FILE_USE;
  697.     } else
  698.         res = OPERATIONFAILED_ERR;
  699. };
  700.     } else
  701.         res = OPERATIONFAILED_ERR;
  702.         } else
  703.         {
  704.             if (stream_id == PARAM_STREAM)
  705.                 device_connected = PARAMETER_USE;
  706.             else
  707.                 res = INVALIDSTREAMID_ERR;
  708.         };
  709.         write_integer (device_connected);
  710.         write_integer (res);
  711.      };
  712. }
  713.  
  714. void stream_access ()
  715. {
  716.     int stream_id;
  717.     if (read_integer (&stream_id))
  718.     {
  719.         int access_method = 0;
  720.         int res = F_OK;
  721.         if (valid_stream(stream_id))
  722.         {
  723.             struct STREAM_DESC *streamp = &filers[stream_id];
  724.             access_method = streamp->access_m;
  725.         } else
  726.         {
  727.             if (stream_id == PARAM_STREAM)
  728.                 access_method = TEXTBYTESTREAM_ACCESS;
  729.             else
  730.             res = INVALIDSTREAMID_ERR;
  731.         };
  732.         write_integer (access_method);
  733.         write_integer (res);
  734.      };
  735. }
  736.  
  737. void stream_length ()
  738. {
  739.     int stream_id;
  740.     if (read_integer (&stream_id))
  741.     {
  742.         int res = F_OK;
  743.         long int len = 0L;
  744.         if (valid_stream(stream_id))
  745.         {
  746.             struct STREAM_DESC *streamp = &filers[stream_id];
  747.             res = seek_file_length(streamp->fileptr, &len);
  748.         } else
  749.         {
  750.             if (stream_id == PARAM_STREAM)
  751.                 len = (long) tcominptr;
  752.             else
  753.                 res = INVALIDSTREAMID_ERR;
  754.         };
  755.         write_long_integer (len);
  756.         write_integer (res);
  757.      };
  758. }
  759.  
  760. void stream_status ()
  761. {
  762.     int stream_id;
  763.     if (read_integer (&stream_id))
  764.     {
  765.         int res = F_OK;
  766.         if (valid_stream(stream_id))
  767.         {
  768.             struct STREAM_DESC *streamp = &filers[stream_id];
  769.             res = streamp->result;
  770.         } else
  771.         {
  772.             if (stream_id == PARAM_STREAM)
  773.             {
  774.                 if (tcominptr == tcomoutptr)
  775.                     res = F_EOF;
  776.                 else
  777.                     res = F_OK;
  778.             } else
  779.                 res = INVALIDSTREAMID_ERR;
  780.         };
  781.         write_integer (res);
  782.      };
  783. }
  784.  
  785. void set_result ()
  786. {
  787.     if (read_integer(&transputer_result))
  788.     {
  789.         write_integer (F_OK);
  790.     }
  791. }
  792.  
  793. void run_command ()
  794. {
  795.     int record_len = 0, res = F_OK;
  796.     char buffer [RECORD_LENGTH + 1];
  797.     if (read_record (&record_len, buffer))
  798.     {
  799.         buffer [record_len] = '\0';
  800.         res = 1;                                  /* If ok, returns 0 */
  801.         if (res != 0)                             /* Not ok, returns -1 */
  802.             write_integer (OPERATIONFAILED_ERR);
  803.         else
  804.             write_integer (F_OK);
  805.     };
  806. }
  807.  
  808. void rename_file ()
  809. {
  810.     int old_len = 0;
  811.     int new_len = 0;
  812.     char old_name [RECORD_LENGTH], new_name [RECORD_LENGTH];
  813.     int res = F_OK;
  814.     if (read_record (&old_len, old_name))
  815.     if (read_record (&new_len, new_name))
  816.     {
  817.         res = rename (new_name, old_name);       /* If ok, returns 0 */
  818.         if (res != 0)                          /* Not ok, returns non-zero */
  819.             write_integer (OPERATIONFAILED_ERR);
  820.         else
  821.             write_integer (F_OK);
  822.     };
  823. }
  824.  
  825. void read_time ()
  826. {
  827.     /* beinhaltet Umrechnung eines bitkodierten Datums (Amiga)  */
  828.     /* auf die Sekunden seit dem 1.1.1970, 0.00 h               */
  829.     long int seconds,dummy;
  830.     (void) time(&dummy);
  831.     seconds =((dummy<<1 )&31L) + (60L*((dummy<<6 )&31L));
  832.     seconds+=(3600L*((dummy<<11)&31L))+(24L*3600L*((dummy<<16)&31L));
  833.     seconds+= (30L*24L*3600L*((dummy<<21)&15L));
  834.     seconds+=(365L*24L*3600L*((dummy<<25)&31L));
  835.     seconds+=(10L*365L*24L*3600L) - (30L*24L*3600L);
  836.     write_long_integer (seconds);
  837.     write_integer (F_OK);
  838. }
  839.  
  840. void read_key ()
  841. {
  842.     int key = 0, key_hit=0;        /*1*/
  843.                      /* character in keyboard buffer ? */
  844.     if (key_hit != 0)                /* returns non-zero if key pressed */
  845.         key = (int)getchar();        /* get key and echo it */
  846.     write_integer (key);
  847.     if (key_hit != 0) 
  848.         write_integer (F_OK);
  849.     else 
  850.     write_integer (OPERATIONFAILED_ERR);
  851. }
  852.  
  853.  
  854. /**** ADD1 begin ****/
  855.  
  856. void run_time_data()
  857. {
  858.    int option;
  859.  
  860.    if (read_integer(&option))
  861.    {
  862.       switch (option)
  863.       {
  864.          case 0:
  865.             write_integer(alien_option_flag);
  866.             write_integer(F_OK);
  867.             break;
  868.          default:
  869.             write_integer(0);
  870.             write_integer(OPERATIONFAILED_ERR);
  871.             break;
  872.       }
  873.    }
  874. }
  875.  
  876.  
  877. void read_environment()
  878. {
  879.    int block_size;
  880.    char buffer[RECORD_LENGTH+1];
  881.  
  882.    if (read_record(&block_size,buffer))
  883.    {
  884.       char *ptr;
  885.       extern char *getenv();
  886.  
  887.       buffer[block_size] = '\0';
  888.       ptr = getenv(buffer);
  889.       if (ptr==NULL)
  890.       {
  891.          write_record(0,"");
  892.          write_integer(OPERATIONFAILED_ERR);
  893.       }
  894.       else
  895.       {
  896.          int record_len=0;
  897.          char record[RECORD_LENGTH+1];
  898.  
  899.          string_to_record(ptr,record,&record_len);
  900.          write_record (record_len,record);
  901.          write_integer(F_OK);
  902.       }
  903.    }
  904. }
  905.  
  906. /****  ADD1 end ****/
  907.  
  908.  
  909. void recieve_block ()
  910. {
  911.     long int source, block_size;
  912.     if (read_long_integer (&source))
  913.     if (read_long_integer (&block_size))
  914.     {
  915.         write_long_record(block_size, (char *) source);
  916.         write_integer(F_OK);
  917.     }
  918. }
  919.  
  920. send_block ()
  921. {
  922.     long int destination, block_size;
  923.     if (read_long_integer (&destination))
  924.     if (read_long_record (&block_size, (char *) destination))
  925.     {
  926.         write_long_integer(block_size);
  927.         write_integer(F_OK);
  928.     }
  929. }
  930.  
  931. /**** ADD2 begin ****/
  932.  
  933. call_interrupt ()
  934. {
  935.    /* NOT AVAILABLE ON AMIGA, JUST KEEP PROTOCOL */
  936.    unsigned char buffer[RECORD_LENGTH+1];
  937.    int interrupt,block_size, res=OPERATIONFAILED_ERR;
  938.  
  939.    if (read_integer(&interrupt))
  940.    if (read_record(&block_size,buffer))
  941.    {
  942.       write_integer(0);
  943.       write_record(0,"");
  944.       write_integer(res);
  945.    }
  946. }
  947.  
  948. read_regs()
  949. {
  950.    /* NOT AVAILABLE ON AMIGA */
  951.    write_record(0,"");
  952.    write_integer(OPERATIONFAILED_ERR);
  953. }
  954.  
  955. void port_read()
  956. {
  957.    /* NOT AVAILABLE ON AMIGA */
  958.    int address;
  959.  
  960.    if (read_integer(&address))
  961.    {
  962.       write_integer(0);
  963.       write_integer(OPERATIONFAILED_ERR);
  964.    }
  965. }
  966.  
  967.  
  968. void port_write()
  969. {
  970.    /* NOT AVAILABLE ON AMIGA */
  971.    int address, value;
  972.  
  973.    if(read_integer(&address))
  974.    if(read_integer(&value))
  975.    {
  976.       write_integer(OPERATIONFAILED_ERR);
  977.    }
  978. }
  979.  
  980. /**** ADD2 end ****/
  981.  
  982. void add_to_tcom (str)
  983. char *str;
  984. {
  985.     char c;
  986.     while ((c = *str++) != '\0')
  987.         tcom[tcominptr++] = c;
  988.     tcom[tcominptr++] = ' ';
  989. }
  990.  
  991. int tcomread (buffer, len)
  992. char *buffer;
  993. int len;
  994. {
  995.     int bytes_read = 0;
  996.     while ( (tcomoutptr < tcominptr) && (bytes_read < len) )
  997.     {
  998.         *buffer++ = tcom[tcomoutptr++];
  999.         bytes_read++;
  1000.     };
  1001.     return (bytes_read);
  1002. }
  1003.  
  1004. int read_number (str)
  1005. char *str;
  1006. {
  1007.     int result = 0;
  1008.     int base;
  1009.     int carry_on;
  1010.     int c;
  1011. if (*str == '#')
  1012. {
  1013.     base = 16; str++;
  1014. } else
  1015.     base = 10;
  1016.     carry_on = TRUE;
  1017.     while (carry_on)
  1018.     {
  1019.        c = *str++;
  1020.         if ((c >= '0') && (c <= '9'))
  1021.             result = (result * base) + c - '0';
  1022.         else
  1023.         {
  1024.             if (base == 16)
  1025.             {
  1026.                 if ((c >= 'a') && (c <= 'f'))
  1027.                     result = (result * base) + 10 + c - 'a';
  1028.                 else
  1029.                 {
  1030.                     if ((c >= 'A') && (c <= 'F'))
  1031.                         result = (result * base) + 10 + c - 'A';
  1032.                     else
  1033.                         carry_on = FALSE;
  1034.                 };
  1035.             } else
  1036.                 carry_on = FALSE;
  1037.         };
  1038.     };
  1039.     return (result);
  1040. }
  1041.  
  1042. int parse_command (argc, argv, boot_file_name)
  1043.   int argc;
  1044.   char *argv[], *boot_file_name;
  1045. /* Parse the command line typed in by the user. */
  1046. {
  1047.     char *ch;
  1048.     int i = 1;
  1049.     strcpy (boot_file_name, DEFAULT_BOOT_FILE);
  1050.     while (i < argc)
  1051.     {
  1052. ch = argv[i++];
  1053. switch (*ch++)
  1054. {
  1055. case '-':
  1056. case '/':
  1057. switch (*ch++)
  1058. {
  1059.     case ':' :
  1060. switch (*ch++)
  1061. {
  1062. case 'b':
  1063. if (i < argc)
  1064. {
  1065.     boot_file_exists = TRUE;
  1066.     strcpy (boot_file_name, argv[i++]);
  1067. }
  1068. else
  1069. {
  1070.     printf ("Missing boot file name parameter\n");
  1071.     return (FALSE);
  1072. };
  1073. break;
  1074. case 'l':
  1075. if (i < argc)
  1076. {
  1077.     link_base = read_number (argv[i++]);
  1078. } else
  1079. {
  1080.     printf ("Missing link address parameter\n");
  1081.     return (FALSE);
  1082. };
  1083. break;
  1084. case 'i':
  1085. printf (version);
  1086. printf ("Copyright INMOS Limited, 1987\n");
  1087. printf ("Amiga-Version modified by SANG-Computersysteme GmbH, 1988\n");
  1088. break;
  1089. case 'e':
  1090. test_error_flag = TRUE;
  1091. break;
  1092. /**** ADD3 begin ****/
  1093. case 'o':
  1094. if (i<argc)
  1095. {
  1096.    alien_option_flag = read_number(argv[i++]);
  1097. }
  1098. else
  1099. {
  1100.    printf("Missing alien option parameter\n");
  1101.    return(FALSE);
  1102. }
  1103. break;
  1104. /**** ADD3 end ****/
  1105. default:
  1106.     add_to_tcom ( argv[i-1] );
  1107.     break;
  1108. };
  1109. break;
  1110.     default :
  1111.         add_to_tcom ( argv[i-1] );
  1112.         break;
  1113. };
  1114. break;
  1115. default:
  1116.     add_to_tcom ( argv[i-1] );
  1117.     break;
  1118. };
  1119.     };
  1120.     return (TRUE);
  1121. }
  1122.  
  1123. void read_link ()
  1124. /* Read a message coming down the link. */
  1125. {
  1126.     if (read_integer (&command))
  1127.     {
  1128. #ifdef DEBUG
  1129.         printf("Transputer sending command %d \n",command);
  1130. #endif
  1131.         switch (command)
  1132. {
  1133. case TERMINATE_CMD:
  1134.     filer_close ();
  1135.     write_integer (F_OK);
  1136.     terminate_server (T_TERMINATED);
  1137.     break;
  1138. case ALIENTERMINATE_CMD:
  1139.     write_integer (F_OK);
  1140.     break;
  1141. case OPENFILE_CMD:
  1142.     open_file (PERMANENT); break;
  1143. case OPENTEMP_CMD:
  1144.     open_temp (); break;
  1145. case OPENINPUTSTREAM_CMD:
  1146.     open_stream (S_INPUT); break;
  1147. case OPENOUTPUTSTREAM_CMD:
  1148.     open_stream (S_OUTPUT); break;
  1149. case STREAMACCESS_CMD:
  1150.     stream_access (); break;
  1151. case STREAMSTATUS_CMD:
  1152.     stream_status (); break;
  1153. case STREAMFILE_CMD:
  1154.     stream_file (); break;
  1155. case STREAMLENGTH_CMD:
  1156.     stream_length (); break;
  1157. case STREAMCONNECT_CMD:
  1158.     stream_connect (); break;
  1159. case CLOSESTREAM_CMD:
  1160.     close_stream (); break;
  1161. case READBLOCK_CMD:
  1162.     read_block (); break;
  1163. case WRITEBLOCK_CMD:
  1164.     write_block (); break;
  1165. case SEEK_CMD:
  1166.     stream_seek (); break;
  1167. case SETRESULT_CMD:
  1168.     set_result (); break;
  1169. case RUNCOMMAND_CMD:
  1170.     run_command (); break;
  1171. case RENAMEFILE_CMD:
  1172.     rename_file (); break;
  1173. case READTIME_CMD:
  1174.     read_time (); break;
  1175. case RUNTIMEDATA_CMD:
  1176.     run_time_data(); break;
  1177. case READENVIRONMENT_CMD:
  1178.     read_environment(); break;
  1179. case READKEY_CMD:
  1180.     read_key (); break;
  1181. case RECIEVEBLOCK_CMD :
  1182.     recieve_block (); break;
  1183. case SENDBLOCK_CMD:
  1184.     send_block (); break;
  1185. /**** ADD4 begin ****/
  1186. case CALLINTERRUPT_CMD:
  1187.     call_interrupt(); break;
  1188. case READREGS_CMD:
  1189.     read_regs(); break;
  1190. case PORTREAD_CMD:
  1191.     port_read(); break;
  1192. case PORTWRITE_CMD:
  1193.     port_write(); break;
  1194. /**** ADD4 end ****/
  1195. default:
  1196.     terminate_server (T_ILLEGAL_COMMAND);
  1197. }
  1198.     };
  1199. }
  1200.  
  1201. void root_error ()
  1202. /* Process an error in the transputer system. */
  1203. {
  1204.     terminate_server (T_TRANSPUTER_ERR);
  1205. }
  1206.  
  1207. void terminate_message (t_code)
  1208. int t_code;
  1209. /* Report the server's reason for termination. */
  1210. {
  1211.     switch (t_code)
  1212.     {
  1213.     case T_TERMINATED:        break;
  1214.     case T_USR_STOP:
  1215.     case T_USR_BRK:
  1216.           fprintf (stderr, "Server aborted by user\n"); break;
  1217.     case T_TRANSPUTER_ERR:
  1218.           fprintf (stderr, 
  1219.                 "Server terminated: error in transputer system\n");
  1220.           break;
  1221.     case T_BAD_BOOT:
  1222.           fprintf (stderr, 
  1223.                 "Server terminated: cannot boot root transputer\n");
  1224.           break;
  1225.     case T_ILLEGAL_COMMAND:
  1226.         fprintf (stderr,
  1227.               "Server terminated: illegal filer command received\n");
  1228.           break;
  1229.     case T_BAD_COMMAND_LINE:
  1230.           fprintf (stderr, "Server terminated: bad command line\n");
  1231.           break;
  1232.     case T_BAD_RECORD:
  1233.           fprintf (stderr,
  1234.                   "Server terminated: bad protocol when expecting record\n");
  1235.           break;
  1236.     case T_BAD_INT32:
  1237.           fprintf (stderr,
  1238.                   "Server terminated: bad protocol when expecting INT32\n");
  1239.           break;
  1240.     }
  1241. }
  1242.  
  1243. int root_init( boot_file_name, analyse_flag )
  1244. char boot_file_name[];
  1245. int analyse_flag;
  1246. /* Initialise the root transputer board by resetting it and sending the boot
  1247.    file to it. */
  1248. {
  1249.     init_root();
  1250.     if (boot_file_exists)
  1251.     {
  1252.         printf ( "Booting root transputer ...\n" ); 
  1253.         if (analyse_flag)
  1254.             reset_analyse_root();
  1255.         else
  1256.             reset_root();
  1257.         return (boot_root ( boot_file_name ));
  1258.     }
  1259.     else
  1260.         return(F_OK);
  1261. }
  1262.  
  1263. void filer_init ()
  1264. {
  1265.     int i;
  1266.     for (i = 0; i < N_STREAMS; i++)
  1267.         filers[i].inuse = FALSE;
  1268. }
  1269.  
  1270. /**** REMARK: DIFFERENT ****/
  1271.  
  1272. int usr_brk_handler (sig)
  1273. int sig;
  1274. /* Process a user break ( control-break on the keyboard ). */
  1275. {
  1276.     terminate_server(T_USR_BRK);
  1277. }
  1278.  
  1279. int server_main()
  1280. {
  1281.    while (running)
  1282.    {
  1283.           if(link_in_test())  read_link();
  1284.      Chk_Abort();
  1285.    }
  1286. }
  1287.  
  1288. int main (argc, argv, envp)
  1289. int argc;
  1290. char *argv[], *envp[];
  1291. {
  1292.     int analyse_flag = FALSE,   /* Boot transputer in analyse mode flag */
  1293.         init_flag;              /* Boot transputer flag */
  1294.     char boot_file_name[FILE_NAME_LENGTH];
  1295.     if (!parse_command(argc, argv, boot_file_name))  /* Parse command line */
  1296.     {
  1297.         terminate_code = T_BAD_COMMAND_LINE;
  1298.         init_flag = FALSE;
  1299.     }
  1300.     else
  1301.         init_flag = TRUE;
  1302.     while (init_flag)
  1303.     {
  1304. running = TRUE;
  1305. init_flag = FALSE;
  1306. terminate_code = 0;
  1307. filer_init();
  1308. if (root_init (boot_file_name, analyse_flag) == F_OK)
  1309. {
  1310. /*    signal (SIGINT, usr_brk_handler); */
  1311.     server_main ();
  1312. switch (terminate_code)
  1313. {
  1314.     case T_TRANSPUTER_ERR:
  1315.         fprintf (stderr, "Error in transputer system\n");
  1316.     case T_USR_BRK:
  1317.     {
  1318.         int key;
  1319.         filer_close();
  1320.         analyse_flag = TRUE;
  1321.         break;
  1322.     }
  1323.     default: break;
  1324. };
  1325. }
  1326. else
  1327.     terminate_code = T_BAD_BOOT;
  1328.     };
  1329.     terminate_message (terminate_code);
  1330.     exit(transputer_result);
  1331. }
  1332.